package com.finger.forest;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.finger.forest.adapter.ChatMessageAdapter;
import com.finger.forest.adapter.ChatMultiItemEntity;
import com.finger.forest.base.BaseActivity;
import com.finger.forest.base.BaseView;
import com.finger.forest.base.ResponseTag;
import com.finger.forest.http.presenter.RegisterPresenter;
import com.finger.forest.model.InsertVoiceModel;
import com.finger.forest.model.VoiceListModel;
import com.finger.forest.mp3.AudioFileFuncWav;
import com.finger.forest.mp3.AudioRecorderWav;
import com.finger.forest.mp3.ErrorCode;
import com.finger.forest.mp3.MP3Converter;
import com.finger.forest.utils.ToastUtils;
import com.finger.forest.utils.UniversalItemDecoration;
import com.jakewharton.rxbinding2.view.RxView;
import com.scwang.smartrefresh.layout.SmartRefreshLayout;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.listener.OnRefreshListener;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

import butterknife.BindView;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;

/**
 * 即时通讯
 */
public class CommunicationActivity extends BaseActivity<RegisterPresenter> implements BaseView {

    /**
     * 返回
     */
    @BindView(R.id.btn_back)
    ImageView backIv;

    @BindView(R.id.smartRL)
    SmartRefreshLayout smartRL;
    @BindView(R.id.rvMessage)
    RecyclerView rvMessage;
    @BindView(R.id.bnVoice)
    Button bnVoice;

    private List<ChatMultiItemEntity> chatMultiItemEntities = new ArrayList<>();
    private ChatMessageAdapter chatMessageAdapter;
    private MediaPlayer mediaPlayer;

    private Timer timer = new Timer();

    private long voiceStartTime = 0;

    private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static final int REQUEST_EXTERNAL_STORAGE2 = 2;
    private static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.RECORD_AUDIO};

    public static void verifyStoragePermissions(Activity activity) {
        // Check if we have write permission
        int permission = ActivityCompat.checkSelfPermission(activity,
                Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (permission != PackageManager.PERMISSION_GRANTED) {
            // We don't have permission so prompt the user
            ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE,
                    REQUEST_EXTERNAL_STORAGE);
        }
    }

    @Override
    protected int setView() {
        return R.layout.activity_communication;
    }

    @Override
    protected void receiveData() {

    }

    @Override
    protected void initializeView() {

        verifyStoragePermissions(CommunicationActivity.this);

        chatMessageAdapter = new ChatMessageAdapter(chatMultiItemEntities);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
        linearLayoutManager.setStackFromEnd(true);
        rvMessage.setLayoutManager(linearLayoutManager);
        rvMessage.setAdapter(chatMessageAdapter);
        rvMessage.addItemDecoration(new UniversalItemDecoration() {
            @Override
            public Decoration getItemOffsets(int position) {
                ColorDecoration colorDecoration = new ColorDecoration();
                if (position == 0) {
                    colorDecoration.top = getResources().getDimensionPixelOffset(R.dimen.dp_10);
                }
                colorDecoration.bottom = getResources().getDimensionPixelOffset(R.dimen.dp_12);
                return colorDecoration;
            }
        });

        chatMessageAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
            @Override
            public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
                ChatMultiItemEntity chatMultiItemEntity = chatMultiItemEntities.get(position);
                if (null != chatMultiItemEntity) {
                    int id = view.getId();
                    int type = chatMultiItemEntity.getItemType();

                    if (type == ChatMultiItemEntity.TYPE_SEND) {
                        VoiceListModel.FileListBean voiceListModel = chatMultiItemEntity.getSendVoiceListModel();
                        if (id == R.id.tvSendVoice) {
                            if (null != voiceListModel) {
                                try {
                                    stopMediaPlayer();
                                    mediaPlayer = new MediaPlayer();
                                    mediaPlayer.reset();
                                    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                                    mediaPlayer.setDataSource(voiceListModel.getFilePath());
                                    if (!mediaPlayer.isPlaying()) {
                                        mediaPlayer.prepare();
                                        mediaPlayer.start();
                                    }
                                } catch (IOException e) {
                                    stopMediaPlayer();
                                    e.printStackTrace();
                                } catch (IllegalStateException e) {
                                    stopMediaPlayer();
                                    e.printStackTrace();
                                }
                            }
                        }
                    }

                    if (type == ChatMultiItemEntity.TYPE_RECEIVE) {
                        VoiceListModel.FileListBean voiceListModel = chatMultiItemEntity.getSendVoiceListModel();
                        if (id == R.id.tvReceive) {
                            if (null != voiceListModel) {
                                try {
                                    stopMediaPlayer();
                                    mediaPlayer = new MediaPlayer();
                                    mediaPlayer.reset();
                                    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                                    mediaPlayer.setDataSource(voiceListModel.getFilePath());

                                    if (!mediaPlayer.isPlaying()) {
                                        mediaPlayer.prepare();
                                        mediaPlayer.start();
                                    }
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                }
            }
        });
        doRequest();
        init();
        clicks();
    }

    public static final int GET_BET_DATA = 0xabc0001;
    public Handler handler = new Handler(Looper.myLooper()) {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case GET_BET_DATA:
                    loadData();
                    sendEmptyMessageDelayed(GET_BET_DATA, 6000);
                    break;
                default:
                    break;
            }
        }
    };


    private void doRequest() {
        handler.sendEmptyMessageDelayed(GET_BET_DATA, 0);
    }


    private void clicks() {
        RxView.clicks(backIv).throttleFirst(2, TimeUnit.SECONDS).subscribe(o -> {
            finish();
        });

        bnVoice.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        Log.e("xxx", "按下");
                        voiceStartTime = new Date().getTime(); //初始化录音开始时间

                        recode(1);
                        bnVoice.setText("录音中...");
                        Log.i("TAG", "开始录音");
                        break;
                    case MotionEvent.ACTION_UP:
                        bnVoice.setText("按住录音");
                        Log.e("xxx", "抬起");
                        Log.i("TAG", "停止录音");
                        int duration = (int) (new Date().getTime() - voiceStartTime) / 1000; //计算录音时间（单位：秒）
                        if (duration <= 0) {
                            stop();
                            ToastUtils.show("语音时间太短");
                            break;
                        }

                        //停止录音
                        stop();
                        //开始转码
                        startConverterMP3();

                        String mp3Path = AudioFileFuncWav.getDiskCachePath(CommunicationActivity.this) + "/FinalAudio.wav";
//                        Log.e("TAG", "onClick: 播放MP3文件 path=" + mp3Path);
                        File mp3File = new File(mp3Path);

                        stopTimer();
                        timer = new Timer();
                        timer.schedule(new TimerTask() {

                            @Override
                            public void run() {
                                //判断文件是否被其他线程占用 若文件被调用，上传时会报错
                                if (mp3File.renameTo(mp3File)) {
                                    //取消定时操作
                                    timer.cancel();
                                    //执行上传音频操作
                                    Map<String, RequestBody> maps = new HashMap<>();
                                    maps.put("gridId", RequestBody.create(MediaType.parse("text/plain;charset=UTF-8"), drUid + ""));
                                    RequestBody requestFile = RequestBody.create(MediaType.parse("audio/mp3"), mp3File);
                                    MultipartBody.Part requestImgPart =
                                            MultipartBody.Part.createFormData("file", mp3File.getPath(), requestFile);
                                    showPd();
                                    presenter.insertVoiceintercom(maps, requestImgPart);
                                }
                            }
                        }, 1500, 1500);
                }
                return true;
            }
        });
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mediaPlayer != null) {
            mediaPlayer.stop();
        }
    }

    @Override
    protected void loadDataFromServer() {
        smartRL.setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh(@NonNull RefreshLayout refreshLayout) {
                loadData();
            }
        });
        smartRL.autoRefresh();
    }

    private void loadData() {
        Map<String, Object> maps = new HashMap<>();
        presenter.voiceintercomByGrui(maps);
    }

    @Override
    public void onSuccess(Object model, int tag, String msg) {
        switch (tag) {
            case ResponseTag.CHECK_VOICE_LIST:
                List<VoiceListModel> voiceListModelList = (List<VoiceListModel>) model;
                if (null != voiceListModelList && voiceListModelList.size() > 0) {
                    chatMultiItemEntities.clear();

                    for (VoiceListModel voiceListModel : voiceListModelList) {
                        if (voiceListModel.getGridId() == drUid) {
                            //右边的
                            for (VoiceListModel.FileListBean fileListBean : voiceListModel.getFileList()) {
                                ChatMultiItemEntity entityRecommend = new ChatMultiItemEntity();
                                entityRecommend.setSendVoiceListModel(fileListBean);
                                entityRecommend.setType(ChatMultiItemEntity.TYPE_SEND);
                                chatMultiItemEntities.add(entityRecommend);
                            }
                        } else {
                            //左边的
                            for (VoiceListModel.FileListBean fileListBean : voiceListModel.getFileList()) {
                                ChatMultiItemEntity entityRecommend = new ChatMultiItemEntity();
                                entityRecommend.setSendVoiceListModel(fileListBean);
                                entityRecommend.setType(ChatMultiItemEntity.TYPE_RECEIVE);
                                chatMultiItemEntities.add(entityRecommend);
                            }
                        }
                    }
                }
                rvMessage.scrollToPosition(chatMultiItemEntities.size() - 1);

                chatMessageAdapter.notifyDataSetChanged();
                break;

            case ResponseTag.INSERT_VOICE_MESSAGE:
                InsertVoiceModel insertVoiceModel = (InsertVoiceModel) model;
                if (null != insertVoiceModel) {
                    ChatMultiItemEntity entityRecommend = new ChatMultiItemEntity();
                    VoiceListModel.FileListBean fileListBean = new VoiceListModel.FileListBean();
                    fileListBean.setFilePath(insertVoiceModel.getFilepath());
                    entityRecommend.setSendVoiceListModel(fileListBean);
                    entityRecommend.setType(ChatMultiItemEntity.TYPE_SEND);
                    chatMultiItemEntities.add(entityRecommend);
                }
//                loadData();
                chatMessageAdapter.notifyDataSetChanged();
                break;
            default:
                break;
        }
        hidePd();
        if (null != smartRL) {
            smartRL.finishRefresh();
        }
    }

    @Override
    public void onError(int errcode, int tag, String message) {
        ToastUtils.show(this, message == null ? "网络异常" : message);
        if (null != smartRL) {
            smartRL.finishRefresh();
        }
    }

    //录音开始
    private int mState = -1; //-1:没再录制，0：录制wav
    private final static int CMD_RECORDING_TIME = 2000;
    private final static int CMD_RECORDFAIL = 2001;
    private final static int CMD_STOP = 2002;
    private UIHandler uiHandler;
    private UIThread uiThread;

    /**
     * 开始录音
     *
     * @param mFlag
     */
    public void recode(int mFlag) {
        if (mState != -1) {
            Log.e(mState + "1", "mState: " + mState);
            Message msg = new Message();
            Bundle b = new Bundle();// 存放数据
            b.putInt("cmd", CMD_RECORDFAIL);
            b.putInt("msg", ErrorCode.E_STATE_RECODING);
            msg.setData(b);
            uiHandler.sendMessage(msg); // 向Handler发送消息,更新UI
            return;
        }
        int mResult = -1;
        AudioRecorderWav mRecord_1 = AudioRecorderWav.getInstance();
        mResult = mRecord_1.startRecordAndFile(CommunicationActivity.this);
        if (mResult == ErrorCode.SUCCESS) {
            mState = mFlag;
            uiThread = new UIThread();
            new Thread(uiThread).start();
        } else {
            Message msg = new Message();
            Bundle b = new Bundle();// 存放数据
            b.putInt("cmd", CMD_RECORDFAIL);
            b.putInt("msg", mResult);
            msg.setData(b);
            uiHandler.sendMessage(msg); // 向Handler发送消息,更新UI
        }
    }

    private void init() {
        uiHandler = new UIHandler();
    }

    private void stop() {
        if (mState != -1) {
            AudioRecorderWav mRecord_1 = AudioRecorderWav.getInstance();
            mRecord_1.stopRecordAndFile();
        }
        if (uiThread != null) {
            uiThread.stopThread();
        }
        if (uiHandler != null)
            uiHandler.removeCallbacks(uiThread);
        Message msg = new Message();
        Bundle b = new Bundle();// 存放数据
        b.putInt("cmd", CMD_STOP);
        b.putInt("msg", mState);
        msg.setData(b);
        uiHandler.sendMessageDelayed(msg, 1000); // 向Handler发送消息,更新UI
        mState = -1;
    }

    class UIHandler extends Handler {
        public UIHandler() {
        }

        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            Log.d("MyHandler", "handleMessage......");
            super.handleMessage(msg);
            Bundle b = msg.getData();
            int vCmd = b.getInt("cmd");
            Log.e("vCmd", "" + vCmd);
            switch (vCmd) {
                case CMD_RECORDING_TIME:
                    int vTime = b.getInt("msg");
                    Log.e("MyHandler", "正在录音中，已录制：" + vTime + " s");
                    break;
                case CMD_RECORDFAIL:
                    int vErrorCode = b.getInt("msg");
                    String vMsg = ErrorCode.getErrorInfo(CommunicationActivity.this, vErrorCode);
                    Log.e("MyHandler", "录音失败：" + vMsg);
//                    Toast.makeText(CommunicationActivity.this, "录音失败：" + vMsg, Toast.LENGTH_LONG).show();
                    break;
                case CMD_STOP:
                    AudioRecorderWav mRecord = AudioRecorderWav.getInstance();
                    long mSize = mRecord.getRecordFileSize();
                    Log.e("MyHandler", "录音已停止.录音文件:" + AudioFileFuncWav.getWavFilePath(CommunicationActivity.this) + "文件大小：" + mSize);
//                    Toast.makeText(CommunicationActivity.this, "录音已停止.录音文件:" + AudioFileFuncWav.getWavFilePath(CommunicationActivity.this) + "文件大小：" + mSize, Toast.LENGTH_LONG).show();
                default:
                    break;
            }
        }
    }

    class UIThread implements Runnable {
        int mTimeMill = 0;
        boolean vRun = true;

        public void stopThread() {
            vRun = false;
        }

        public void run() {
            while (vRun) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                mTimeMill++;
                Message msg = new Message();
                Bundle b = new Bundle();// 存放数据
                b.putInt("cmd", CMD_RECORDING_TIME);
                b.putInt("msg", mTimeMill);
                Log.e("TAG" + "2", "stop: " + mTimeMill);
                msg.setData(b);
                uiHandler.sendMessage(msg); // 向Handler发送消息,更新UI
            }
        }
    }

    /**
     * 将录音文件wav转为MP3
     */
    long fileSize;
    long bytes = 0;

    private void startConverterMP3() {
        /*final String wavPath = AudioFileFuncWav.getDiskCachePath(CommunicationActivity.this) + "/FinalAudio.wav";
        final String mp3Path = AudioFileFuncWav.getDiskCachePath(CommunicationActivity.this) + "/converter.mp3";
        MP3Converter.init(44100, 1, 0, 44100, 96, 9);
        fileSize = new File(wavPath).length();
        Log.e("fileSize", fileSize + "  大小");
        new Thread(new Runnable() {
            @Override
            public void run() {
                MP3Converter.convertMp3(wavPath, mp3Path);
            }
        }).start();
        handlerMP3.postDelayed(runnableMP3, 500);*/
    }

    Handler handlerMP3 = new Handler();
    Runnable runnableMP3 = new Runnable() {
        @Override
        public void run() {
            bytes = MP3Converter.getConvertBytes();
            float progress = (100f * bytes / fileSize);
            if (bytes == -1) {
                progress = 100;
            }
            Log.e("TAG", "run: 转码");
            if (handlerMP3 != null && progress != 100) {
                /*Toast.makeText(CommunicationActivity.this, "转码结束" +
                        AudioFileFuncWav.getDiskCachePath(CommunicationActivity.this) + "/converter.mp3", Toast.LENGTH_LONG).show();*/
                handlerMP3.postDelayed(this, 1000);
            } else {
                handlerMP3.removeCallbacksAndMessages(null);
            }
        }
    };

    private void stopMediaPlayer() {
        if (null != mediaPlayer) {
            mediaPlayer.stop();
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }

    private void stopTimer() {
        if (null != timer) {
            timer.cancel();
            timer.purge();
            timer = null;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        stopMediaPlayer();
        stopTimer();

        if (null != handler) {
            handler.removeCallbacksAndMessages(null);
            handler = null;
        }
    }
}
